#include "VCityApp.h"

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
	VCityApp app(hInstance, L"Virtual City", D3DDEVTYPE_HAL, D3DCREATE_SOFTWARE_VERTEXPROCESSING);
	g_pApp = &app;
	return g_pApp->run();
}

VCityApp::VCityApp(HINSTANCE p_hInstance, LPTSTR p_sName, D3DDEVTYPE p_devType, DWORD p_requestedVP)
: App(p_hInstance, p_sName, p_devType, p_requestedVP)
{
	if(!checkDevCaps())
	{
		MessageBox(0, L"Lower Capabcibility!", L"ERROR", MB_OK);
		PostQuitMessage(0);
	}	
	if (AddFontResource(TEXT("chlorinar.ttf")))
	{
		PostMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
	}
}

VCityApp::~VCityApp()
{
	if (m_pCurrentState)
	{
		delete m_pCurrentState;
		m_pCurrentState = 0;
	}
	RemoveFontResourceEx(TEXT("chlorinar.ttf"), FR_PRIVATE, 0);
	ReleaseCOM(g_pD3dDev);
	ReleaseCOM(m_pD3dObject);
}

bool VCityApp::checkDevCaps()
{
	return true;
}

int VCityApp::run()
{
	switchScreenMode();
	MSG msg;
	msg.message = WM_NULL;

	__int64 cps = 0;
	QueryPerformanceFrequency((LARGE_INTEGER*)&cps);
	float spc = 1.0f/cps;

	__int64 t0 = 0;
	QueryPerformanceCounter((LARGE_INTEGER*)&t0);
	__int64 t1;

	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			if(isDevReady())
			{
				QueryPerformanceCounter((LARGE_INTEGER*)&t1);
				m_pCurrentState->update((t1- t0)*spc);
				m_pCurrentState->draw();
			}
		}
	}
	return (int)msg.wParam;
}

LRESULT VCityApp::msgProc(UINT p_uMsg, WPARAM p_wParam, LPARAM p_lParam)
{
	switch(p_uMsg)
	{
	case WM_EXITSIZEMOVE:
		m_d3dPP.BackBufferWidth = LOWORD(p_lParam);
		m_d3dPP.BackBufferHeight = HIWORD(p_lParam);
		m_pCurrentState->onLostDevice();
		HR(g_pD3dDev->Reset(&m_d3dPP));
		m_pCurrentState->onResetDevice();
		return 0;
	case WM_CLOSE:
		DestroyWindow(m_hWnd);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(m_hWnd, p_uMsg, p_wParam, p_lParam);
}